import { _decorator, Component, Node, Button, Sprite, SpriteFrame, UIOpacity, tween, Vec3, Color, director } from 'cc';
import { BoardManager } from '../core/BoardManager';

const { ccclass, property } = _decorator;

/**
 * 方块类型枚举
 */
export enum TileType {
    NONE = -1,
    RED = 0,
    BLUE = 1,
    GREEN = 2,
    YELLOW = 3,
    PURPLE = 4,
    MAX = 5
}

/**
 * 方块组件
 * 负责单个方块的表现和交互
 */
@ccclass('Tile')
export class Tile extends Component {
    @property({type: [SpriteFrame], tooltip: "方块的不同类型贴图"})
    public tileSprites: SpriteFrame[] = [];
    
    @property(Sprite)
    public sprite: Sprite = null;
    
    @property(Button)
    private button: Button = null;
    
    @property(UIOpacity)
    private opacity: UIOpacity = null;
    
    @property({type: Color})
    private selectedColor: Color = new Color(255, 255, 255, 255);
    
    @property({type: Color})
    private normalColor: Color = new Color(255, 255, 255, 255);
    
    // 方块数据
    private _type: TileType = TileType.NONE;
    private _row: number = -1;
    private _col: number = -1;
    private _isSelected: boolean = false;
    private _isMatched: boolean = false;
    
    private _boardManager: BoardManager = null;
    
    // 生命周期函数
    onLoad() {
        this.findBoardManager();
        
        // 确保有Button组件
        if (!this.button) {
            this.button = this.addComponent(Button);
        }
        
        // 注册点击事件
        this.button.node.on(Button.EventType.CLICK, this.onClick, this);
    }
    
    onDestroy() {
        // 移除事件监听
        if (this.button && this.button.node) {
            this.button.node.off(Button.EventType.CLICK, this.onClick, this);
        }
    }
    
    /**
     * 查找BoardManager实例
     */
    private findBoardManager(): void {
        if (!this._boardManager) {
            const boardManagerNode = director.getScene().getChildByName('BoardManager');
            if (boardManagerNode) {
                this._boardManager = boardManagerNode.getComponent(BoardManager);
            }
            
            if (!this._boardManager) {
                console.warn('未找到BoardManager引用，方块功能可能无法正常工作');
            }
        }
    }
    
    /**
     * 初始化方块
     */
    public init(type: TileType, row: number, col: number): void {
        this._type = type;
        this._row = row;
        this._col = col;
        this._isSelected = false;
        this._isMatched = false;
        
        this.updateView();
    }
    
    /**
     * 更新方块视觉表现
     */
    private updateView(): void {
        if (!this.sprite) return;
        
        // 设置方块图片
        if (this._type >= 0 && this._type < this.tileSprites.length) {
            this.sprite.spriteFrame = this.tileSprites[this._type];
        }
    }
    
    /**
     * 点击方块事件处理
     */
    private onClick(): void {
        // 发送点击事件到棋盘管理器
        if (this._boardManager) {
            this._boardManager.selectTile(this);
        }
    }
    
    /**
     * 设置选中状态
     */
    public setSelected(selected: boolean): void {
        if (this._isSelected === selected) return;
        
        this._isSelected = selected;
        
        // 显示选中/取消选中效果
        if (this.sprite) {
            this.sprite.color = selected ? this.selectedColor : this.normalColor;
            
            // 播放选中/取消选中动画
            if (selected) {
                tween(this.node)
                    .to(0.1, { scale: new Vec3(1.1, 1.1, 1) })
                    .start();
            } else {
                tween(this.node)
                    .to(0.1, { scale: new Vec3(1.0, 1.0, 1) })
                    .start();
            }
        }
    }
    
    /**
     * 更新方块位置
     */
    public updatePosition(row: number, col: number): void {
        this._row = row;
        this._col = col;
        
        // 获取棋盘管理器的方块大小和间距
        if (this._boardManager) {
            const tileSize = this._boardManager.getTileSize();
            const tileGap = this._boardManager.getTileGap();
            
            const x = col * (tileSize + tileGap);
            const y = -row * (tileSize + tileGap);
            
            // 使用动画移动方块
            tween(this.node)
                .to(0.3, { position: new Vec3(x, y, 0) }, {
                    easing: 'bounceOut'
                })
                .start();
        }
    }
    
    /**
     * 播放消除动画
     */
    public playEliminateEffect(): void {
        // 播放消除动画
        const opacity = this.getComponent(UIOpacity) || this.addComponent(UIOpacity);
        
        tween(this.node)
            .to(0.2, { scale: new Vec3(1.2, 1.2, 1) })
            .start();
            
        tween(opacity)
            .to(0.4, { opacity: 0 })
            .call(() => {
                // 动画结束后移除节点
                this.node.destroy();
            })
            .start();
    }
    
    /**
     * 设置方块类型
     */
    public setType(type: TileType): void {
        if (type !== this._type) {
            this._type = type;
            this.updateView();
            
            // 播放类型变化的动画效果
            tween(this.node)
                .to(0.1, { scale: new Vec3(0.8, 0.8, 1) })
                .to(0.1, { scale: new Vec3(1.0, 1.0, 1) })
                .start();
        }
    }
    
    /**
     * 设置匹配状态
     */
    public setMatched(matched: boolean): void {
        this._isMatched = matched;
        
        // 匹配状态的视觉提示
        if (this.opacity) {
            this.opacity.opacity = matched ? 200 : 255;
        }
    }
    
    /**
     * 播放移动动画
     */
    public playMoveAnimation(targetPos: Vec3, callback?: Function): void {
        tween(this.node)
            .to(0.2, { position: targetPos })
            .call(() => {
                if (callback) callback();
            })
            .start();
    }
    
    /**
     * 方块选中方法
     */
    public select(): void {
        this.setSelected(true);
    }
    
    /**
     * 方块取消选中方法
     */
    public deselect(): void {
        this.setSelected(false);
    }
    
    // 属性访问器
    public get type(): TileType {
        return this._type;
    }
    
    public get row(): number {
        return this._row;
    }
    
    public set row(value: number) {
        this._row = value;
    }
    
    public get col(): number {
        return this._col;
    }
    
    public set col(value: number) {
        this._col = value;
    }
    
    public get isSelected(): boolean {
        return this._isSelected;
    }
    
    public get isMatched(): boolean {
        return this._isMatched;
    }
} 